﻿using Microsoft.EntityFrameworkCore;
using Abp.Zero.EntityFrameworkCore;
using SOEI.Solution.Authorization.Roles;
using SOEI.Solution.Authorization.Users;
using SOEI.Solution.MultiTenancy;
using SOEI.Solution.EntityFrameworkCore.EntityMapper;
using System.Linq;
using E;
using SOEI.Solution.EntityMapper;

namespace SOEI.Solution.EntityFrameworkCore
{
    public partial class SolutionDbContext : AbpZeroDbContext<Tenant, Role, User, SolutionDbContext>
    {
        /* Define a DbSet for each entity of the application */

        /* DbSet 实体移动到 SolutionDbSet 文件中  */

        public SolutionDbContext(DbContextOptions<SolutionDbContext> options)
            : base(options)
        {
          
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // 设置内置表前缀
            modelBuilder.ChangeAbpTablePrefix<Tenant, Role, User>(AppCoreConst.SchemaNames.TABLE_PREFIX);

            var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();
            // 设置自定义表前缀
            //foreach (var entityType in entityTypes)
            //{
            //    if (entityType.ClrType
            //        .GetCustomAttributes(typeof(TableAttribute), true)
            //        .FirstOrDefault() is TableAttribute table)
            //    {
            //        // 如果你的表名就是实体类型名的话，可以修改为如下形式，就不必给出[table]的Name参数
            //        // string tableName = tablePrefix + entityType.ClrType.Name;
            //        // 如若有其他需求也可在此进行修改
            //        string tableName = AppCoreConst.SchemaNames.TABLE_PREFIX + table.Name;
            //        modelBuilder.Entity(entityType.ClrType)
            //            .ToTable(tableName.ToUpper());
            //    }
            //}

            //判断当前数据库是Oracle 需要手动添加Schema(DBA提供的数据库账号名称)
            if (this.Database.IsOracle())
            {
                modelBuilder.HasDefaultSchema("FGXT_YW");

                
                // 解决Oracle11g 使用的时候数据库长度超出30限制
                this.SetUseOracleEntityColumn(modelBuilder);

                this.SetFrameworkCoreExtensions(modelBuilder);
            }

            // 代码生成器生成的表配置类添加到SetUserTablePrefix方法中
           
            this.SetUserTablePrefix(modelBuilder);

            // 调用基类方法
            base.OnModelCreating(modelBuilder);  
        }

        /// <summary>
        ///  配置用户表
        /// </summary>
        /// <param name="modelBuilder"></param>
        //protected void SetUserTablePrefix(ModelBuilder modelBuilder)
        //{
        //    // 代码生成器生成的表实体配置全部添加到这里
        //    // modelBuilder.ApplyConfiguration(new CompanyMapper());

        //}


        protected void SetFrameworkCoreExtensions(ModelBuilder modelBuilder)
        {
            E.EntityFrameworkCoreTableViewExtensions.SetCaseType(ColumnNameCaseType.Upper);
            E.EntityFrameworkCoreTableViewExtensions.UseColumnNameMaxLength = true;
            E.EntityFrameworkCoreTableViewExtensions.ColumnNameMaxLength = 30;
            var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();

            foreach (var entityType in entityTypes)
            {
                modelBuilder.Entity(entityType.ClrType).CaseAllColumnName();
                //modelBuilder.Entity(entityType.ClrType).CaseTableName();
            }
            // 禁用 使用DbSet名称作为表名和视图名称,优先读Table标记,其次类名
            /*E.EntityFrameworkCoreTableViewExtensions.UseDbSetNameToTableName = false;

            // 设置大写
            E.EntityFrameworkCoreTableViewExtensions.SetCaseType(ColumnNameCaseType.Upper);

            // 使用列名长度限制,最大30
            E.EntityFrameworkCoreTableViewExtensions.UseColumnNameMaxLength = true;
            E.EntityFrameworkCoreTableViewExtensions.ColumnNameMaxLength = 30;

            // 使用默认字符串长度
            E.EntityFrameworkCoreTableViewExtensions.UseDefaultStringMaxLength = true;
            E.EntityFrameworkCoreTableViewExtensions.DefaultStringMaxLength = 256;

            //E.EntityFrameworkCoreTableViewExtensions.CaseAllColumnName
            // 自定义 字符串列数据长度 是否设置默认长度 校验函数
            E.EntityFrameworkCoreTableViewExtensions.CheckUseDefaultStringMaxLength = (type, prop) =>
            {

                var checkResult = new CheckUseDefaultStringMaxLenghtResult();

                // 如果实体的命名空间为 TestWebApp.Database.Models 则设置长度为200
                if (type.Namespace.StartsWith("TestWebApp.Database.Models"))
                {
                    checkResult.Success = true;
                    checkResult.MaxLength = 200;
                }


                return checkResult;
            };*/


            // 将名为 YourContext 中的所有 DbSet 和 DbQuery 的表名、视图名、列名转换为大写 
            // 参数为 true,则 自动跳过处理 DbContext 程序集中已实现的 IEntityTypeConfiguration 和 IQueryTypeConfiguration 
            // modelBuilder.SetAllDbSetTableNameAndColumnName<YourContext>(/* true */);
            // modelBuilder.SetAllDbQueryViewNameAndColumnName<YourContext>(/* true */);
            //modelBuilder.CaseAllDbSetNameAndColumnName<SolutionDbContext>(true);

           
        }


        /// <summary>
        ///  配置用户表
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected void SetUserTablePrefix(ModelBuilder modelBuilder)
        {

            //新添加的实体
            this.SetNewUserTablePrefix(modelBuilder);
            //以前的实体
            this.SetOldUserTablePrefix(modelBuilder);
            // 代码生成器生成的表实体配置全部添加到这里
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected void SetUseOracleEntityColumn(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new AbpEditionsMapper());
            modelBuilder.ApplyConfiguration(new AbpNotificationsMapper());
            modelBuilder.ApplyConfiguration(new AbpNotificationSubscriptionsMapper());
            modelBuilder.ApplyConfiguration(new AbpOrganizationUnitsMapper());
            modelBuilder.ApplyConfiguration(new AbpOrganizationUnitRolesMapper());
            modelBuilder.ApplyConfiguration(new AbpTenantNotificationsMapper());
            modelBuilder.ApplyConfiguration(new AbpUsersMapper());
            modelBuilder.ApplyConfiguration(new AbpEditionFeatureSettingMapper());
            modelBuilder.ApplyConfiguration(new AbpTenantFeatureSettingMapper());
            modelBuilder.ApplyConfiguration(new AbpFeatureSettingMapper());
            modelBuilder.ApplyConfiguration(new AbpEntityChangesMapper());

            modelBuilder.ApplyConfiguration(new AbpRolesMapper());

            modelBuilder.ApplyConfiguration(new AbpSettingsMapper());

            modelBuilder.ApplyConfiguration(new AbpTenantsMapper());

            modelBuilder.ApplyConfiguration(new AbpUserClaimsMapper());

            modelBuilder.ApplyConfiguration(new AbpUserLoginsMapper());

            modelBuilder.ApplyConfiguration(new AbpUserRolesMapper());

            modelBuilder.ApplyConfiguration(new AbpUserTokensMapper());

            modelBuilder.ApplyConfiguration(new AbpUserAccountsMapper());

            modelBuilder.ApplyConfiguration(new AbpEntityPropertyChangesMapper());


            modelBuilder.ApplyConfiguration(new AbpPermissionSettingMapper());
            modelBuilder.ApplyConfiguration(new AbpRolePermissionSettingMapper());
            modelBuilder.ApplyConfiguration(new AbpUserPermissionSettingMapper());

            modelBuilder.ApplyConfiguration(new AbpRoleClaimsMapper());

            modelBuilder.ApplyConfiguration(new AbpAuditLogsMapper());

            modelBuilder.ApplyConfiguration(new AbpBackgroundJobsMapper());

            modelBuilder.ApplyConfiguration(new AbpEntityChangeSetsMapper());

            modelBuilder.ApplyConfiguration(new AbpLanguagesMapper());

            modelBuilder.ApplyConfiguration(new AbpLanguageTextsMapper());

            modelBuilder.ApplyConfiguration(new AbpUserLoginAttemptsMapper());

            modelBuilder.ApplyConfiguration(new AbpUserNotificationsMapper());

            modelBuilder.ApplyConfiguration(new AbpUserOrganizationUnitsMapper());
            modelBuilder.ApplyConfiguration(new AbpDynamicPropertiesMapper());
            modelBuilder.ApplyConfiguration(new AbpDynamicPropertyValuesMapper());
            //5.8.1 新增加的
            modelBuilder.ApplyConfiguration(new AbpWebhookEventsMapper());
            modelBuilder.ApplyConfiguration(new AbpWebhookSubscriptionsMapper());
            modelBuilder.ApplyConfiguration(new AbpWebhookSendAttemptsMapper());
            modelBuilder.ApplyConfiguration(new AbpDynamicEntityPropertiesMapper());
            modelBuilder.ApplyConfiguration(new AbpDynamicEntityPropertyValuesMapper());
            
        }
    }
}
